package com.sugon.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.sugon.consts.BaseConsts;
import com.sugon.consts.SparePartScarpStatus;
import com.sugon.dao.ScarpListDao;
import com.sugon.dao.SparePartDao;
import com.sugon.entity.*;
import com.sugon.modules.sparepart.consts.MaterialBaseConst;
import com.sugon.modules.sparepart.consts.SpPlanAbcEnum;
import com.sugon.modules.sparepart.model.vo.SpScarpEaParam;
import com.sugon.modules.workflow.consts.OaWorkflowProcesses;
import com.sugon.service.*;
import com.sugon.utils.Constant;
import com.sugon.utils.ProcessInfoEnum;
import com.sugon.utils.ShiroUtils;
import com.sugon.utils.SysMsgType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 报废清单(新)Service实现类
 *
 * @author sugon
 * @date 2020-02-10 16:37:15
 */
@Service("scarpListService")
public class ScarpListServiceImpl implements ScarpListService {

    @Resource
    private ScarpListDao scarpListDao;
    @Resource
    private SparePartDao sparePartDao;
    @Resource
    private SysMsgService sysmsgService;
    @Resource
    private DeviceInfoService deviceInfoService;
    @Resource
    private SysOaProcessService processService;
    @Resource
    private DevRetreadRecordService devRetreadRecordService;

    @Override
    public ScarpListEntity queryObject(String id) {
        return scarpListDao.queryObject(id);
    }

    @Override
    public int check(ScarpListEntity scarpList) {
        // 1、更新报废明细审核状态
        int rows = scarpListDao.update(scarpList);
        if (rows > 0) {
            // 如果是审核通过的需要实时计算备件报废数
            if (BaseConsts.PASSED == scarpList.getStatus()) {
                scarpList = queryObject(scarpList.getId());
                if (scarpList != null) {
                    // 更新备件报废数
                    sparePartDao.realtimeUpdateScarpNum(scarpList.getSpareId());
                    // 发送消息
                    SysMsgEntity sysMsgEntity = new SysMsgEntity();
                    sysMsgEntity.setDataId(scarpList.getId());
                    sysMsgEntity.setDataType(ProcessInfoEnum.SPA_BJBF);
                    sysMsgEntity.setDataFlag(SysMsgType.DATA_DEL_END);
                    sysmsgService.allMsgData(sysMsgEntity);
                }
            }
        }
        return rows;
    }

    @Override
    public List<ScarpListEntity> queryList(Map<String, Object> map) {
        return scarpListDao.queryList(map);
    }

    @Override
    public int queryTotal(Map<String, Object> map) {
        return scarpListDao.queryTotal(map);
    }

    @Override
    public int save(ScarpListEntity scarpList) {
        scarpList.setId(RandomUtil.randomString(32));
        scarpList.setCreateTime(DateUtil.date());
        scarpList.setCreateUser(ShiroUtils.getUserId());
        scarpList.setDelFlag(Integer.valueOf(Constant.IS_NOT_DEL));
        int rows = scarpListDao.save(scarpList);
        if (rows > 0) {
            SysMsgEntity msgEntity = new SysMsgEntity();
            String Id = scarpList.getId();
            msgEntity.setDataId(Id);
            msgEntity.setDataUrl("../spare/scarplist.html?Id=" + Id);
            sysmsgService.addApproveItem(ProcessInfoEnum.SPA_BJBF, msgEntity, 0);
        }
        return rows;
    }

    @Override
    public int update(ScarpListEntity scarpList) {
        scarpList.setUpdateTime(new Date());
        scarpList.setUpdateUser(ShiroUtils.getUserId());
        int rows = scarpListDao.update(scarpList);
        if (rows > 0) {
            SysMsgEntity msgEntity = new SysMsgEntity();
            String Id = scarpList.getId();
            msgEntity.setDataId(Id);
            msgEntity.setDataUrl("../spare/scarplist.html?Id=" + Id);
            sysmsgService.addApproveItem(ProcessInfoEnum.SPA_BJBF, msgEntity, 0);
        }
        return rows;
    }

    @Override
    public int delete(String id) {
        return scarpListDao.delete(id);
    }

    @Override
    public int deleteBatch(String[] ids) {
        return scarpListDao.deleteBatch(ids);
    }

    @Override
    public void doScrap(SparePartConsumRecordEntity consumingRecord) {
        // 为防止重复，删除已经生成的记录
        scarpListDao.deleteByConsumingRecordId(consumingRecord.getId());
        // 生成报废记录
        if (consumingRecord.getNum() > 0) {
            ScarpListEntity scarpItem = new ScarpListEntity();
            SparePartEntity sparePart = sparePartDao.queryObject(consumingRecord.getSparePartId());
            Assert.notNull(sparePart);
            DeviceInfoEntity device = deviceInfoService.queryObject(consumingRecord.getDevId());
            Assert.notNull(device);
            scarpItem.setConsumingRecordId(consumingRecord.getId());
            scarpItem.setRepairRecordId(consumingRecord.getBusinessId());
            scarpItem.setSpareId(sparePart.getId());
            scarpItem.setSubEquip(consumingRecord.getDevId());
            scarpItem.setName(sparePart.getName());
            scarpItem.setUseUnit(StrUtil.sub(device.getDeptCode(), 0, 4));
            scarpItem.setSpecs(sparePart.getSpec());
            scarpItem.setScarpNum(consumingRecord.getNum());
            scarpItem.setLine(device.getDevProductCode());
            /*
                如果备件是已审批通过的C-消类型的备件，直接报废
                其他类型的备件，走正常处理流程
             */
            if (SpPlanAbcEnum.CONSUME.getValue().equals(sparePart.getPlanAbc())) {
                scarpItem.setStatus(SparePartScarpStatus.SCARP.getValue());
            } else {
                scarpItem.setStatus(SparePartScarpStatus.CJ_EA_ING.getValue());
            }
            save(scarpItem);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void check(SpScarpEaParam approveParam) {
        // 跳转地址
        Integer approveState = approveParam.getState();
        // 获取报废记录
        List<ScarpListEntity> scarpRecordList = approveParam.getScarpRecordList();
        for (ScarpListEntity scarpRecord : scarpRecordList) {
            // 获取备件信息
            SparePartEntity sparePart = sparePartDao.queryObject(scarpRecord.getSpareId());
            Assert.notNull(sparePart);
            // 获取工作项名称
            String workItemName;
            if (NumberUtil.equals(SparePartScarpStatus.CJ_EA_ING.getValue(), scarpRecord.getStatus())) {
                workItemName = "车间审核是否可修复";
            } else {
                workItemName = "PE审核是否可修复";
            }
            // 获取修旧利废记录
            List<DevRetreadRecordEntity> devRetreadRecords = CollectionUtil.newArrayList();
            if (MaterialBaseConst.AUDIT_PASSED.equals(approveState)) {
                // 给报废记录设置修复方式
                scarpRecord.setStatus(SparePartScarpStatus.CZ_ING.getValue());
                // 根据报废数拆分成修旧利废记录
                Integer scarpNum = scarpRecord.getScarpNum();
                for (int i = 0; i < scarpNum; i++) {
                    // 不论是哪一级审核通过，都会自动生成自主修复台账
                    DevRetreadRecordEntity devRetreadRecord = new DevRetreadRecordEntity();
                    // 修旧利废的归属单位同报废记录的单位一样
                    devRetreadRecord.setBtUnit(scarpRecord.getUseUnit());
                    devRetreadRecord.setType(1);
                    devRetreadRecord.setSpareId(scarpRecord.getSpareId());
                    devRetreadRecord.setMatterCode(sparePart.getErpCode());
                    devRetreadRecord.setOrigVal(NumberUtil.mul(sparePart.getPrice(), 1));
                    devRetreadRecord.setRetNum(1);
                    // 默认为待修复
                    devRetreadRecord.setIsFixed(0);
                    devRetreadRecord.setScarpRecordId(scarpRecord.getId());
                    devRetreadRecord.setRepairRecordId(scarpRecord.getRepairRecordId());
                    // 实施单位默认当前车架
                    devRetreadRecord.setExpUnit(scarpRecord.getUseUnit());
                    devRetreadRecords.add(devRetreadRecord);
                }
            } else {
            /*
                如果是PE工程师的场景：最终报废，生成报废记录
                如果是车间工程时审核不能继续的 -> PE工程师
             */
                if (NumberUtil.equals(SparePartScarpStatus.PE_EA_ING.getValue(), scarpRecord.getStatus())) {
                    scarpRecord.setStatus(SparePartScarpStatus.SCARP.getValue());
                } else {
                    scarpRecord.setStatus(SparePartScarpStatus.PE_EA_ING.getValue());
                }
            }
            // 1、更新备件报废状态
            update(scarpRecord);
            // 2、按需保存修旧利废记录
            if (CollectionUtil.isNotEmpty(devRetreadRecords)) {
                for (DevRetreadRecordEntity devRetreadRecord : devRetreadRecords) {
                    devRetreadRecordService.save(devRetreadRecord);
                }
            }
            // 3、记录OA审批结果
            processService.generateProcessHandleRecord(OaWorkflowProcesses.SP_SCARP.getBusType(), scarpRecord.getId(), workItemName, approveParam.getState(), approveParam.getCheckRemark());
        }
    }
}
